#ifndef NP_MOVER_MOVER_H
#define NP_MOVER_MOVER_H

#ifndef NETTAO_MOVER_H
#define NETTAO_MOVER_H

#include <map>
#include <string>
#include <boost/lexical_cast.hpp>
#include <config/Structures.h>
#include <dao/DaoArticle.h>
#include <dao/DaoChapter.h>
#include <dao/DaoAttach.h>
#include <utils/XTimer.h>
#include "Builder.h"
#include "OpfBuilder.h"

class Mover
{
public:
  Mover(void);

  ~Mover(void);

  void working();

private:
  articleInfo::ArticleInfo m_articleTarget;

  articleInfo::ArticleInfo* m_articleListSource;

  chapterInfo::ChapterInfo* m_chapterListTarget;

  chapterInfo::ChapterInfo* m_chapterListSource;

  attachInfo::AttachInfo* m_attachListTarget;

  attachInfo::AttachInfo* m_attachListSource;

  map<std::string, DaoArticle*> m_mapsArticleDAO;

  map<std::string, DaoChapter*> m_mapsChapterDAO;

  //add by san
  map<std::string, DaoAttach*> m_mapsAttachDAO;

  map<std::string, Builder*> m_mapsBuilder;

  OpfBuilder m_opfBuilder;

  map<std::string, std::string> m_mapsArticleID;

  map<std::string, std::string> m_mapsChapterID;

  //add by san
  map<std::string, std::string> m_mapsAttachID;

  char m_logMsg[mover::SIZE_LOG_MSG];        /*< 全局日志信息存储 >*/

  mover::WebInfo m_webinfo;

  configInfo::ConfigInfo* m_currentConfig;             /*< 当前线程执行使用的配置文件 >*/

  int m_configLen;

  std::string m_flagTarget;

  std::string m_flagSource;

  std::string m_flag;

  int m_repeatTimes;

  int m_articleIndex;                 /*< 标明当前数组的下标>*/

  int m_lastTargetChapterCount;       /*< 记录当前已存在的章节数 >*/

  bool m_articleExists;

  int m_sourceChapterRecCount;

  int m_targetChapterRecCount;

private:
  void initialize();

//  void addDAO(const configInfo::ConfigInfo& config);
  void addDAO(const std::string& target, const std::string& source);

  void addBuilder(const configInfo::ConfigInfo& config);

  //void maxIDAutoPlus(std::string& str);
  inline void maxIDAutoPlus(std::string& str)
  {
    std::string strTmp(str);
    int intTmp =boost::lexical_cast<int>(str);
    str = boost::lexical_cast<std::string>(intTmp + 1);
  }

  //void resetArticle();
  inline void resetArticle()
  {
    m_articleTarget.articleid.assign(m_mapsArticleID[m_flag]);
    //resetArticle(m_mapsArticleID[m_flag]);
    m_articleTarget.lastchapter.clear();
    m_articleTarget.lastchapterid.clear();
    m_articleTarget.lastvolume.clear();
    m_articleTarget.lastvolumeid.clear();
  }
  void copyArticle(const articleInfo::ArticleInfo& articleSource, articleInfo::ArticleInfo& article);

  void copyChapter(const chapterInfo::ChapterInfo& sourceChapter, chapterInfo::ChapterInfo& targetChapter);

  void analyseNextPage(const int flag, const int posBegin);

  //void assignArticle(const Article& articleSource, Article& article);

  inline void assignArticle(const articleInfo::ArticleInfo& articleSource, articleInfo::ArticleInfo& article)
  {
//    memset((void *)&article, 0x00, sizeof(article));
    //article.articleid.assign(articleSource.articleid);
    article.siteid.assign(articleSource.siteid);
    article.postdate.assign(articleSource.postdate);
    //edit by san
    article.lastupdate.assign(boost::lexical_cast<string>( XTimer::getDateTime()));
//    article.lastupdate.assign(articleSource.lastupdate);
    article.articlename.assign(articleSource.articlename);
    article.keywords.assign(articleSource.keywords);
    article.initial=articleSource.initial;
    article.authorid.assign(articleSource.authorid);
    article.author.assign(articleSource.author);
    article.posterid.assign(articleSource.posterid);
    article.poster.assign(articleSource.poster);
    article.agentid.assign(articleSource.agentid);
    article.agent.assign(articleSource.agent);
    article.sortid.assign(articleSource.sortid);
    article.ctypeid.assign(articleSource.ctypeid);
    article.intro.assign(articleSource.intro);
    article.notice.assign(articleSource.notice);
    article.setting.assign(articleSource.setting);
    //article.lastvolumeid.assign(articleSource.lastvolumeid);
    //article.lastvolume.assign(articleSource.lastvolume);
    //article.lastchapterid.assign(articleSource.lastchapterid);
    //article.lastchapter.assign(articleSource.lastchapter);
    article.chapters.assign(articleSource.chapters);
    article.size.assign(articleSource.size);
    article.lastvisit.assign(articleSource.lastvisit);
    article.dayvisit.assign(articleSource.dayvisit);
    article.weekvisit.assign(articleSource.weekvisit);
    article.monthvisit.assign(articleSource.monthvisit);
    article.allvisit.assign(articleSource.allvisit);
    article.lastvote.assign(articleSource.lastvote);
    article.dayvote.assign(articleSource.dayvote);
    article.weekvote.assign(articleSource.weekvote);
    article.monthvote.assign(articleSource.monthvote);
    article.allvote.assign(articleSource.allvote);
    article.vipvotetime.assign(articleSource.vipvotetime);
    article.vipvotenow.assign(articleSource.vipvotenow);
    article.vipvotepreview.assign(articleSource.vipvotepreview);
    article.goodnum.assign(articleSource.goodnum);
    article.badnum.assign(articleSource.badnum);
    article.toptime.assign(articleSource.toptime);
    article.saleprice.assign(articleSource.saleprice);
    article.salenum.assign(articleSource.salenum);
    article.totalcost.assign(articleSource.totalcost);
    article.articletype=articleSource.articletype;
    article.permission=articleSource.permission;
    article.firstflag=articleSource.firstflag;
    article.fullflag=articleSource.fullflag;
    article.imgflag=articleSource.imgflag;
    article.power=articleSource.power;
    article.display=articleSource.display;

    article.articleid =  m_mapsArticleID[m_flag];
    maxIDAutoPlus(m_mapsArticleID[m_flag]);
    article.lastchapter.clear();
    article.lastchapterid.clear();
    article.lastvolume.clear();
    article.lastvolumeid.clear();
  }

  //void assignChapter(const Chapter& sourceChapter, Chapter& targetChapter);
  inline void assignChapter(const chapterInfo::ChapterInfo& sourceChapter, chapterInfo::ChapterInfo& targetChapter)
  {
    targetChapter.articlename.assign(sourceChapter.articlename);
    targetChapter.attachment.assign(sourceChapter.attachment);
    targetChapter.chapterid.assign(sourceChapter.chapterid);
    targetChapter.chaptername.assign(sourceChapter.chaptername);
    targetChapter.chapterorder.assign(sourceChapter.chapterorder);
    targetChapter.chaptertype = sourceChapter.chaptertype;
    targetChapter.ctype.assign(sourceChapter.ctype);
    targetChapter.display = sourceChapter.display;
    targetChapter.isnew = sourceChapter.isnew;
    targetChapter.volumeid.assign(sourceChapter.volumeid);
    targetChapter.txtlink.assign(sourceChapter.txtlink);
    targetChapter.totalcost.assign(sourceChapter.totalcost);
    targetChapter.size.assign(sourceChapter.size);
    targetChapter.siteid.assign(sourceChapter.siteid);
    targetChapter.saleprice.assign(sourceChapter.saleprice);
    targetChapter.salenum.assign(sourceChapter.salenum);
    targetChapter.preview_page.assign(sourceChapter.preview_page);
    targetChapter.power = sourceChapter.power;
    targetChapter.posterid.assign(sourceChapter.posterid);
    targetChapter.poster.assign(sourceChapter.poster);
    targetChapter.postdate.assign(sourceChapter.postdate);
    targetChapter.next_page.assign(sourceChapter.next_page);
    targetChapter.lastupdate.assign(sourceChapter.lastupdate);
    targetChapter.isvip = sourceChapter.isvip;
    targetChapter.sourcearticleid.assign(sourceChapter.articleid);    /*< 目标站的小说ID>*/
    targetChapter.sourcechapterid.assign(sourceChapter.chapterid);    /*< 目标站的章节ID>*/
  }

  void getNovelList();

  /**
   * 重置内部变量
   */
  //void resetInteriorVariable();
  inline void resetInteriorVariable()
  {
    m_articleExists = true;
    m_sourceChapterRecCount = 0;
    m_targetChapterRecCount = 0;
    m_lastTargetChapterCount = 0;
    m_opfBuilder.initialize();
  }

  bool getNovel();

  void getChapterList();

  void getAttachList(const chapterInfo::ChapterInfo& sourceChapter,
                            const chapterInfo::ChapterInfo& targetChapter);

  inline bool comfirmTransaction()
  {
    m_articleTarget.chapters = boost::lexical_cast<std::string>(m_targetChapterRecCount);
    m_articleTarget.lastchapterid = m_chapterListTarget[m_targetChapterRecCount-1].chapterid;
    m_articleTarget.lastchapter = m_chapterListTarget[m_targetChapterRecCount-1].chaptername;
    m_articleTarget.lastvolumeid = m_chapterListTarget[m_targetChapterRecCount-1].volumeid;
//    m_articleTarget.lastvolume = m_chapterListTarget[m_targetChapterRecCount-1];//最后一卷的问题?
    if(m_mapsChapterDAO[m_flagTarget]->confirmCacheTran())
    {
      if(!m_articleExists)
      {
        m_mapsArticleDAO[m_flagTarget]->addArticle(m_articleTarget);
      }
      else
      {
        m_mapsArticleDAO[m_flagTarget]->updateArticle(m_articleTarget);
      }
    }
    return true;
  }

  void completeNovel();
};

#endif

#endif // NP_MOVER_MOVER_H
